package main.java.com.lee.juc;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.IntStream;

/**
 * @Description TODO
 * @Author winston
 * @DateTime 2022/1/13
 */
public class ReentrantLockDemo {
    private static int sum = 0;
    public static void main(String[] args) throws InterruptedException {
//        ReentrantLock reentrantLock = new ReentrantLock();
//        reentrantTest(reentrantLock);
//        add(reentrantLock);
        MyCLHLock myCLHLock = new MyCLHLock();
        add(myCLHLock);
    }

    public static void reentrantTest(Lock lock) {
        lock.lock();
        System.out.println("加锁成功1");
        lock.lock();
        System.out.println("加锁成功2");
        lock.unlock();
        lock.unlock();
    }

    public static void add(Lock lock) throws InterruptedException {
        long start = System.currentTimeMillis();
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        CountDownLatch countDownLatch = new CountDownLatch(10);
        IntStream.rangeClosed(1, 10).forEach(i->{
            countDownLatch.countDown();
            executorService.submit(() -> increment(lock));
        });
        countDownLatch.await();
        executorService.shutdown();
        while (!executorService.isTerminated()) {

        }
        System.out.println(sum);
        System.out.println("耗费时间: "+(System.currentTimeMillis() - start));
    }

    public static void increment(Lock lock) {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName());
            IntStream.rangeClosed(1, 100000).forEach(i->{
                sum++;
            });
        }finally {
            lock.unlock();
        }
    }

    public static void increment2(Lock lock) {
        if (lock.tryLock()) {
            try {
                System.out.println(Thread.currentThread().getName());
                IntStream.rangeClosed(1, 100).forEach(i->{
                    sum++;
                });
            }finally {
                lock.unlock();
            }
        }
    }

    public static void increment3(Lock lock) throws InterruptedException {
        if (lock.tryLock(1, TimeUnit.SECONDS)) {
            try {
                System.out.println(Thread.currentThread().getName());
                IntStream.rangeClosed(1, 100).forEach(i->{
                    sum++;
                });
            }finally {
                lock.unlock();
            }
        }
    }
}
